#include "hierarchical_cache.h"
#include <iostream>
#include <random>
#include <chrono>
#include <vector>
#include <iomanip>

// 测试数据结构
struct TestData {
    int id;
    char data[1024];  // 模拟1KB的数据

    TestData() : id(0) {
        std::memset(data, 0, sizeof(data));
    }

    TestData(int i) : id(i) {
        std::snprintf(data, sizeof(data), "TestData_%d", i);
    }
};

// 性能测试函数
template<typename CacheType>
void performanceTest(CacheType& cache, const std::string& test_name) {
    std::cout << "\n********** " << test_name << " 性能测试 **********" << std::endl;

    const int num_operations = 10000;
    const int data_range = 5000;
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(0, data_range - 1);

    // 预热阶段 - 填充缓存
    std::cout << "预热阶段：填充缓存..." << std::endl;
    for (int i = 0; i < data_range / 2; ++i) {
        cache.put(i, TestData(i));
    }

    // 测试写入性能
    std::cout << "\n测试写入性能..." << std::endl;
    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < num_operations; ++i) {
        int key = dis(gen);
        cache.put(key, TestData(key));
    }
    auto end = std::chrono::high_resolution_clock::now();
    auto write_duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    double write_ops_per_sec = (num_operations * 1000000.0) / write_duration.count();

    std::cout << "写入操作数: " << num_operations << std::endl;
    std::cout << "写入耗时: " << write_duration.count() / 1000.0 << " ms" << std::endl;
    std::cout << "写入吞吐量: " << std::fixed << std::setprecision(2)
              << write_ops_per_sec << " ops/sec" << std::endl;

    // 测试读取性能（高命中率场景）
    std::cout << "\n测试读取性能（高命中率）..." << std::endl;
    start = std::chrono::high_resolution_clock::now();
    int hits = 0;
    for (int i = 0; i < num_operations; ++i) {
        int key = dis(gen) % (data_range / 4);  // 限制范围以提高命中率
        TestData value;
        if (cache.get(key, value)) {
            hits++;
        }
    }
    end = std::chrono::high_resolution_clock::now();
    auto read_duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    double read_ops_per_sec = (num_operations * 1000000.0) / read_duration.count();

    std::cout << "读取操作数: " << num_operations << std::endl;
    std::cout << "读取耗时: " << read_duration.count() / 1000.0 << " ms" << std::endl;
    std::cout << "读取吞吐量: " << std::fixed << std::setprecision(2)
              << read_ops_per_sec << " ops/sec" << std::endl;
    std::cout << "实际命中率: " << (hits * 100.0 / num_operations) << "%" << std::endl;

    // 测试混合负载（读写混合）
    std::cout << "\n测试混合负载（70%读取，30%写入）..." << std::endl;
    std::uniform_int_distribution<> op_dis(1, 10);
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < num_operations; ++i) {
        int key = dis(gen);
        if (op_dis(gen) <= 7) {  // 70%读取
            TestData value;
            cache.get(key, value);
        } else {  // 30%写入
            cache.put(key, TestData(key));
        }
    }
    end = std::chrono::high_resolution_clock::now();
    auto mixed_duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    double mixed_ops_per_sec = (num_operations * 1000000.0) / mixed_duration.count();

    std::cout << "混合操作数: " << num_operations << std::endl;
    std::cout << "混合耗时: " << mixed_duration.count() / 1000.0 << " ms" << std::endl;
    std::cout << "混合吞吐量: " << std::fixed << std::setprecision(2)
              << mixed_ops_per_sec << " ops/sec" << std::endl;
}

// 功能测试函数
void functionalTest() {
    std::cout << "\n========== 功能测试 ==========" << std::endl;

    // 创建分层缓存系统
    // L1: 100个条目，最大10MB内存
    // L2: 1000个条目，最大100MB磁盘空间
    HierarchicalCache<int, TestData> cache(
        100,        // L1容量
        10,         // L1最大内存（MB）
        1000,       // L2容量
        "./cache",  // L2缓存目录
        100         // L2最大磁盘（MB）
    );

    std::cout << "\n1. 测试基本的put/get操作..." << std::endl;
    for (int i = 0; i < 10; ++i) {
        cache.put(i, TestData(i));
    }

    TestData value;
    bool found = cache.get(5, value);
    std::cout << "查找key=5: " << (found ? "成功" : "失败");
    if (found) {
        std::cout << ", value.id=" << value.id << std::endl;
    } else {
        std::cout << std::endl;
    }

    std::cout << "\n2. 测试缓存淘汰（L1到L2）..." << std::endl;
    for (int i = 10; i < 150; ++i) {
        cache.put(i, TestData(i));
    }

    // 检查早期的数据是否还能找到（应该在L2中）
    found = cache.get(0, value);
    std::cout << "查找key=0（应该在L2中）: " << (found ? "成功" : "失败") << std::endl;

    std::cout << "\n3. 测试批量操作..." << std::endl;
    std::vector<int> keys = {1, 5, 10, 50, 100, 999};
    auto results = cache.getBatch(keys);
    std::cout << "批量查询" << keys.size() << "个key，找到" << results.size() << "个" << std::endl;

    std::cout << "\n4. 测试缓存预热..." << std::endl;
    std::vector<std::pair<int, TestData>> preload_data;
    for (int i = 200; i < 210; ++i) {
        preload_data.emplace_back(i, TestData(i));
    }
    cache.preload(preload_data);
    std::cout << "预加载" << preload_data.size() << "条数据完成" << std::endl;

    std::cout << "\n5. 测试删除操作..." << std::endl;
    cache.remove(5);
    found = cache.get(5, value);
    std::cout << "删除key=5后查找: " << (found ? "失败（不应该找到）" : "成功（已删除）") << std::endl;

    // 打印统计信息
    cache.printStatistics();
}

// LRU算法测试
void lruAlgorithmTest() {
    std::cout << "\n========== LRU算法验证测试 ==========" << std::endl;

    // 创建一个小容量的缓存来验证LRU行为
    LRUCache<int, std::string> lru_cache(3);  // 容量为3

    std::cout << "\n插入3个元素（容量满）..." << std::endl;
    lru_cache.put(1, "A");
    lru_cache.put(2, "B");
    lru_cache.put(3, "C");
    std::cout << "缓存内容: 3(C) -> 2(B) -> 1(A)" << std::endl;

    std::cout << "\n访问key=1..." << std::endl;
    std::string val;
    lru_cache.get(1, val);
    std::cout << "缓存内容: 1(A) -> 3(C) -> 2(B)" << std::endl;

    std::cout << "\n插入新元素key=4（应该淘汰2）..." << std::endl;
    lru_cache.put(4, "D");
    bool found = lru_cache.contains(2);
    std::cout << "key=2是否存在: " << (found ? "是（错误）" : "否（正确）") << std::endl;
    std::cout << "缓存内容: 4(D) -> 1(A) -> 3(C)" << std::endl;

    std::cout << "\n更新已存在的key=3..." << std::endl;
    lru_cache.put(3, "C_updated");
    std::cout << "缓存内容: 3(C_updated) -> 4(D) -> 1(A)" << std::endl;

    std::cout << "\nLRU算法验证完成！" << std::endl;
}

int main() {
    std::cout << "==============================================\n";
    std::cout << "       C++11 分层缓存系统演示程序              \n";
    std::cout << "==============================================\n";

    try {
        // 1. LRU算法验证测试
        lruAlgorithmTest();

        // 2. 功能测试
        functionalTest();

        // 3. 性能测试 - 仅内存缓存
        std::cout << "\n\n==============================================\n";
        MemoryCache<int, TestData> mem_cache(1000, 50);
        performanceTest(mem_cache, "纯内存缓存（L1）");

        // 4. 性能测试 - 仅磁盘缓存
        std::cout << "\n\n==============================================\n";
        DiskCache<int, TestData> disk_cache(1000, "./disk_cache", 100);
        performanceTest(disk_cache, "纯磁盘缓存（L2）");

        // 5. 性能测试 - 分层缓存
        std::cout << "\n\n==============================================\n";
        HierarchicalCache<int, TestData> hier_cache(500, 25, 2000, "./hier_cache", 200);
        performanceTest(hier_cache, "分层缓存（L1+L2）");

        std::cout << "\n\n==============================================\n";
        std::cout << "              所有测试完成！                    \n";
        std::cout << "==============================================\n";

    } catch (const std::exception& e) {
        std::cerr << "错误: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}